/*
 * Leaflet Esri Tile Layer
 *
 * Copyright (c) 2015, kyo (sinokyo@163.com)
 */

L.TileLayer.EsriTileLayer = L.TileLayer.extend({
	initialize: function(url, options) {
		url += '/tile/{z}/{y}/{x}';
		L.TileLayer.prototype.initialize.call(this, url, options);
	}
});

L.tileLayer.esriTileLayer = function(url, options) {
	return new L.TileLayer.EsriTileLayer(url, options);
};

/*
 * Leaflet Esri Tile Layer - High DPI
 *
 * Copyright (c) 2016, kyo (sinokyo@163.com)
 */

L.TileLayer.EsriHighDpiTileLayer = L.TileLayer.extend({
	initialize: function(url, options) {
		url += '/tile/{z}/{y}/{x}';
		L.TileLayer.prototype.initialize.call(this, url, options);
	},
	
	getTileUrl: function(tilePoint) {
		return L.Util.template(this._url, L.extend({
			s: this._getSubdomain(tilePoint),
			z: tilePoint.z - 1,
			x: tilePoint.x,
			y: tilePoint.y
		}, this.options));
	}
});

L.tileLayer.esriHighDpiTileLayer = function(url, options) {
	return new L.TileLayer.EsriHighDpiTileLayer(url, options);
};

/*
 * Leaflet Tencent Tile Layer
 *
 * Copyright (c) 2015, kyo (sinokyo@163.com)
 */

L.TileLayer.TencentTileLayer = L.TileLayer.extend({
	urls: {
		'street': 'proxy.jsp?http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0',
		'satellite': 'proxy.jsp?http://p{s}.map.gtimg.com/sateTiles/{z}/{r}/{c}/{x}_{y}.jpg',
		'satellite-road': 'proxy.jsp?http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=2',
		'dem': 'proxy.jsp?http://p{s}.map.gtimg.com/demTiles/{z}/{r}/{c}/{x}_{y}.jpg',
		'dem-road': 'proxy.jsp?http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=1'
	},
	
	initialize: function(name, options) {
		if (!name) {
			return;
		}
		options = options || {};
		options.subdomains = '0123';
		options.tms = true;
	    L.Util.setOptions(this, options);
	    
	    this.tileArgsHandle = {
			'street': this._streetArgs,
			'satellite': this._satelliteArgs,
			'satellite-road': this._streetArgs,
			'dem': this._satelliteArgs,
			'dem-road': this._streetArgs
		};
	    this.name = name;
	    var url = this._getUrl(name);
	    L.TileLayer.prototype.initialize.call(this, url, options);
	},
	
    _getUrl: function(name) {
    	return this.urls[name];
    },
	
    getTileUrl: function(tilePoint) {
    	return L.Util.template(this._url, this._getTileArgs(tilePoint));
    },
    
    _getTileArgs: function(tilePoint) {
    	return this.tileArgsHandle[this.name].call(this, tilePoint);
    },
    
    _streetArgs: function(tilePoint) {
    	return {
    		s: this._getSubdomain(tilePoint),
    		x: tilePoint.x,
    		y: Math.pow(2, tilePoint.z) - 1 - tilePoint.y,
    		z: tilePoint.z
        };
    },
    
    _satelliteArgs: function(tilePoint) {
    	return {
    		s: this._getSubdomain(tilePoint),
    		x: tilePoint.x,
    		//y: tilePoint.y,//leaflet0.7.3
    		y: Math.pow(2, tilePoint.z) - 1 - tilePoint.y,//leaflet1.0.0
    		z: tilePoint.z,
    		r: Math.floor(tilePoint.x / 16),
    		c: Math.floor((Math.pow(2, tilePoint.z) - 1 - tilePoint.y) / 16)
        };
    }
});

L.tileLayer.tencentTileLayer = function(name, options) {
    return new L.TileLayer.TencentTileLayer(name, options);
};

/*
 * Leaflet Mapbox Tile Layer
 * 
 * Map names: 
 * 		streets, light, dark, satellite, streets-satellite, wheatpaste,
 * 		streets-basic, comic, outdoors, run-bike-hike, pencil, pirates, high-contrast
 *
 * Copyright (c) 2015, kyo (sinokyo@163.com)
 */

L.TileLayer.MapboxTileLayer = L.TileLayer.extend({
	url: 'https://{s}.tiles.mapbox.com/v4/mapbox.{name}/{z}/{x}/{y}.png',
	token: '?access_token=pk.eyJ1IjoiYW5hbHl0aWNhbGdyYXBoaWNzIiwiYSI6IjA2YzBjOTM3YzFlYzljYmQ5NDAxZWI1Y2ZjNzZlM2E1In0.vDZL2SPFEpi_f7ziAIP_yw',
	
	initialize: function(name, options) {
		if (!name) {
			return;
		}
		options = options || {};
		options.subdomains = 'abcd';
		options.tms = true;
	    L.Util.setOptions(this, options);
	    
	    var url = this._getUrl(name);
	    L.TileLayer.prototype.initialize.call(this, url, options);
	},
	
    _getUrl: function(name) {
    	return this.url.replace('{name}', name) + this.token;
    },
	
    getTileUrl: function(tilePoint) {
    	return L.Util.template(this._url, this._getTileArgs(tilePoint));
    },
    
    _getTileArgs: function(tilePoint) {
    	return {
    		s: this._getSubdomain(tilePoint),
    		x: tilePoint.x,
    		y: Math.pow(2, tilePoint.z) - tilePoint.y - 1,
    		z: tilePoint.z
        };
    }
});

L.tileLayer.mapboxTileLayer = function(name, options) {
    return new L.TileLayer.MapboxTileLayer(name, options);
};

/*
 * Leaflet Stamen Tile Layer
 *
 * Copyright (c) 2015, kyo (sinokyo@163.com)
 */

L.TileLayer.StamenTileLayer = L.TileLayer.extend({
	urls: {
		'watercolor': 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg',
		'toner': 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png',
		'terrain': 'http://{s}.tile.stamen.com/terrain/{z}/{x}/{y}.jpg'	// only USA
	},
	
	initialize: function(name, options) {
		if (!name) {
			return;
		}
		options = options || {};
		options.subdomains = 'abcd';
		options.tms = true;
	    L.Util.setOptions(this, options);
	    
	    var url = this._getUrl(name);
	    
	    if (!url) {
	    	return;
	    }
	    L.TileLayer.prototype.initialize.call(this, url, options);
	},
	
    _getUrl: function(name) {
    	return this.urls[name];
    },
	
    getTileUrl: function(tilePoint) {
    	return L.Util.template(this._url, this._getTileArgs(tilePoint));
    },
    
    _getTileArgs: function(tilePoint) {
    	return {
    		s: this._getSubdomain(tilePoint),
    		x: tilePoint.x,
    		y: Math.pow(2, tilePoint.z) - tilePoint.y - 1,
    		z: tilePoint.z
        };
    }
});

L.tileLayer.stamenTileLayer = function(name, options) {
    return new L.TileLayer.StamenTileLayer(name, options);
};